import './style.scss';

interface BarouselOptions<E extends HTMLElement> {
  width?: number;
  height?: number;
  list: string[];
  el: string | E;
  /**
   * @default true
   */
  mask?: boolean;
  /**
   * @default true
   */
  dots?: boolean;
}

export class Barousel {
  public width: number;

  public height: number;

  public currentIndex = 0;

  public list: string[];

  public el: HTMLDivElement;

  public wrapper: HTMLDivElement;

  public options: BarouselOptions<HTMLDivElement>;

  public items: HTMLDivElement[] = [];

  public dot: HTMLSpanElement | null = null;

  public dots: HTMLSpanElement[] = [];

  constructor(options: BarouselOptions<HTMLDivElement>) {
    this.width = options.width ? options.width : 1080;
    this.height = options.height ? options.height : (420 * 65) / 100;
    this.list = options.list;
    this.options = { ...options, mask: true, dots: true };
    this.el = options.el instanceof HTMLDivElement
      ? options.el
      : document.querySelector<HTMLDivElement>(options.el || '.barousel')!;

    this.wrapper = this.el.querySelector<HTMLDivElement>('.barousel-wrapper')!;

    if (this.options.mask) {
      this.wrapper.classList.add('mask');
    }
    this.init();
  }

  public init() {
    this.el.style.height = `${this.height}px`;
    this.el.style.width = `${this.width}px`;
    this.wrapper.style.perspective = `${this.width}px`;
    this.items = this.renderItem();
    if (this.options.dots) {
      this.dots = this.renderDots();
      this.clickDotsListener = this.clickListenerHandl.bind(this);
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      this.dot!.addEventListener('click', this.clickDotsListener);
    }

    this.setClass();

    this.clickListener = this.clickListenerHandl.bind(this);
    this.wrapper.addEventListener('click', this.clickListener);
  }

  public renderItem() {
    const fg = document.createDocumentFragment();
    const items: HTMLDivElement[] = [];

    this.list.forEach((img, i) => {
      const item = document.createElement('div');
      item.style.backgroundImage = `url(${img})`;
      item.classList.add('barousel-item');
      item.setAttribute('item-index', String(i));

      fg.appendChild(item);
      items.push(item);
    });

    this.wrapper.appendChild(fg);
    return items;
  }

  public setClass() {
    this.items.forEach((el, i) => {
      const next = this.currentIndex === this.list.length - 1 ? 0 : this.currentIndex + 1;
      const prev = this.currentIndex === 0 ? this.list.length - 1 : this.currentIndex - 1;
      console.log(next, prev);

      if (this.options.dots) {
        if (this.currentIndex === i) {
          this.dots[i].classList.add('current');
        } else {
          this.dots[i].classList.remove('current');
        }
      }

      switch (i) {
        case this.currentIndex:
          el.classList.add('active');
          el.classList.remove('next', 'prev');
          break;
        case next:
          el.classList.add('next');
          el.classList.remove('active', 'prev');
          break;
        case prev:
          el.classList.add('prev');
          el.classList.remove('active', 'next');
          break;
        default:
          setTimeout(() => el.classList.remove('next', 'prev', 'active'));
      }
    });
  }

  public clickListenerHandl(e: MouseEvent) {
    const target = e.target as HTMLElement | null;
    if (!target) return;

    const index = target.getAttribute('item-index')!;
    console.log(index);
    this.currentIndex = Number(index);
    this.setClass();
  }

  public clickListener(e: MouseEvent) {}

  public clickDotsListener(e: MouseEvent) {}

  public renderDots() {
    this.dot = this.el.querySelector<HTMLDivElement>('.barousel-dots')!;
    const fg = document.createDocumentFragment();
    const dots: HTMLSpanElement[] = [];

    for (let i = 0; i < this.items.length; i++) {
      const span = document.createElement('span');
      span.setAttribute('item-index', String(i));
      fg.appendChild(span);
      dots.push(span);
    }

    this.dot.appendChild(fg);
    return dots;
  }
}
